﻿using System;
using System.Text;
using System.Threading;

namespace AV2BV
{
    public static class AV2BV
    {
        #region --私有方法+私有常量--
        /*只读，虽然没有什么用，是私有的*/
        private static readonly int[] _ = { 11, 10, 3, 8, 4, 6, 2, 9, 5, 7 };
        private static string base58(this int id)
        {
            string base58 = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
            return base58.ToCharArray()[id].ToString();
        }

        private static int base58(this char id)
        {
            string base58 = "fZodR9XQDSUm21yCkr6zBqiveYah8bt4xsWpHnJE7jL5VG3guMTKNPAwcF";
            for (int i = 0; i < base58.ToCharArray().Length; i++)
            {
                if (id.Equals(base58.ToCharArray()[i]))
                {
                    return i;
                }
            }
            return -1;
        }

        private static string String(this string[] str)
        {
            StringBuilder @string = new StringBuilder();
            for (int i = 0; i < str.Length; i++)
            {
                @string.Append(str[i]);
            }
            return @string.ToString();
        }
        #endregion

        #region --扩展--
        public static string toAV(this string bv)
        {
            char[] x = bv.ToCharArray();
            long r = 0;
            for (int i = 0; i < 10; i++)
            {
                r += x[_[i]].base58() * (long)Math.Pow(58, i);
            }
            return "av" + ((r - 100618342136696320) ^ 177451812);
        }

        public static string toBV(this string av)
        {
            try
            {
                int xx = 0;
                xx = int.Parse(av.Trim().Remove(0, 2));
                long x = xx ^ 177451812;
                /*坑点
                 不知道什么原因，反正加上不会错
                 之前在控制台应用测试的时候
                 x+=100618342136696320;和Interlocked.Add(ref x, 100618342136696320);执行后的x值不相同
                 到了窗体应用这两个执行后x值相同
                 */
                Interlocked.Add(ref x, 100618342136696320);
                string[] bv = new string[12];
                bv[0] = "B";
                bv[1] = "V";
                for (int i = 0; i < 10; i++)
                {
                    /*这里Math.Pow要换成long,不能换成int*/
                    bv[_[i]] = ((int)(x / (long)Math.Pow(58, i) % 58)).base58();
                }
                return bv.String();
            }
            catch
            {
                return null;
            }
        }

        public static string toBV(this int av)
        {
            long x = av ^ 177451812;
            Interlocked.Add(ref x, 100618342136696320);
            string[] bv = new string[12];
            bv[0] = "B";
            bv[1] = "V";
            for (int i = 0; i < 10; i++)
            {
                /*这里Math.Pow要换成long,不能换成int*/
                bv[_[i]] = ((int)(x / (long)Math.Pow(58, i) % 58)).base58();
            }
            return bv.String();
        }
        #endregion
    }
}
